package controllers;

import models.Entities;
import models.IdeaDeveloper;
import models.Log;
import models.Notification;
import models.Organization;
import models.Organizer;

import com.google.gson.JsonObject;

import play.mvc.Controller;
import play.mvc.With;
import java.util.*;

/**
 * 
 * @author Maryam
 * 
 */
@With(Secure.class)
public class BlockIdeaDeveloper extends Controller {

	public static void BlockIdeaDeveloper() {
		render();
	}

	/**
	 * gets the members in entity
	 * 
	 * @param entityId
	 *            the entity where members are being rendered
	 */
	public static void getMembers(long entityId) {
		try {
			Entities entity = (Entities) Entities.find("id =?", entityId)
					.fetch().get(0);

			String members = "";
			JsonObject json = new JsonObject();
			members += "&" + entity.members.get(0).username;
			for (int i = 1; i < entity.members.size(); i++) {
				if (IdeaDeveloper.isMemberEntity(entity.members.get(i), entity)) {
					members += "&" + entity.members.get(i).username;
				}
			}
			if (members == "")
				members = "No Members";
			else
				members = members.substring(1, members.length());
			json.addProperty("members", members);
			renderJSON(json.toString());
		} catch (Exception e) {
			JsonObject json = new JsonObject();
			json.addProperty("members", "Exception happened!");
			renderJSON(json.toString());
		}
	}

	/**
	 * This method is used to block an ideaDeveloper from a certain entity by an
	 * organizer
	 * 
	 * @author Maryam
	 * 
	 * @param ideadeveloperName
	 *            The name of the ideaDeveloper that is going to be blocked
	 * @param entityId
	 *            the id of the entity that the ideaDeveloper will be blocked
	 *            from
	 */

	public static void blockFromEntity(String ideadeveloperName, long entityId) {

		JsonObject json = new JsonObject();
		Long loggedInUserID = Security.userid();

		IdeaDeveloper ideadev = IdeaDeveloper.findById(loggedInUserID);
		long countEntities = Entities.count("id = ?", entityId);
		if (countEntities == 0) {
			json.addProperty("output", "Entity not found");
		} else {

			Entities entity = (Entities) Entities.find("id = ?", entityId)
					.fetch().get(0);

			boolean hasAuthority = ideadev.canLeadEntity(ideadev, entity);
			long countUser = IdeaDeveloper.count("username = ?",
					ideadeveloperName);
			if (countUser == 0) {
				json.addProperty("output", "User not found");
			} else {

				IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
						.find("username = ?", ideadeveloperName).fetch().get(0);
				boolean isMember = entity.members.contains(ideaDeveloper);
				boolean isOrganizer = false;
				for (int i = 0; i < entity.managers.size(); i++) {
					if (entity.managers.get(i).ideaDeveloper
							.equals(ideaDeveloper)) {
						isOrganizer = true;
					}
				}
				if (isOrganizer) {
					json.addProperty("output",
							"Sorry user cant be blocked,they're an organizer to this entity");
				} else {
					boolean isLead = false;
					Organization org = entity.liesIn;
					for (int i = 0; i < org.managers.size(); i++) {
						if (org.managers.get(i).ideaDeveloper
								.equals(ideaDeveloper)) {
							isLead = true;
						}
					}
					if (isLead) {
						json.addProperty(
								"output",
								"Sorry user cant be blocked,they're an organzation lead to the organization that the entity specified lies in");
					} else {
						if (!isMember) {
							json.addProperty("output",
									"Idea developer is not a member in this entity");
						} else {
							if (hasAuthority) {
								if (!ideaDeveloper.blockedEnt.contains(entity)) {
									ideaDeveloper.blockedEnt.add(entity);
									entity.blocked.add(ideaDeveloper);
									ideaDeveloper.save();
									entity.save();
									Log log = new Log("^ blocked from entity ^");
									log.ids = ideadev.id + ","
											+ ideaDeveloper.id;
									log.types = "developer,developer";
									log.save();
									json.addProperty("output",
											"Idea developer has been blocked from entity");
								} else {
									json.addProperty("output",
											"Idea developer is already blocked from this entity");
								}
							} else {
								json.addProperty("output",
										"Sorry u have no authority on this entity");
							}
						}
					}
				}
			}
		}
		renderJSON(json.toString());

	}

	/**
	 * This method is used to unblock an ideaDeveloper from a certain entity by
	 * an organizer
	 * 
	 * @author Maryam
	 * 
	 * @param ideadeveloperName
	 *            The name of the ideaDeveloper that is going to be unblocked
	 * @param entityName
	 *            the name of the entity that the ideaDeveloper will be
	 *            unblocked from
	 */
	public static void unblockFromEntity(String ideadeveloperName, long entityId) {

		JsonObject json = new JsonObject();
		Long loggedInUserID = Security.userid();

		IdeaDeveloper ideadev = IdeaDeveloper.findById(loggedInUserID);
		long countEntities = Entities.count("id = ?", entityId);
		if (countEntities == 0) {
			json.addProperty("output", "Entity not found");
		} else {

			Entities entity = (Entities) Entities.find("id = ?", entityId)
					.fetch().get(0);

			boolean hasAuthority = ideadev.canLeadEntity(ideadev, entity);
			long countUser = IdeaDeveloper.count("username = ?",
					ideadeveloperName);
			if (countUser == 0) {
				json.addProperty("output", "User not found");
			} else {

				IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
						.find("username = ?", ideadeveloperName).fetch().get(0);
				boolean isMember = entity.members.contains(ideaDeveloper);

				if (!isMember) {
					json.addProperty("output",
							"Idea developer is not a member in this entity");
				} else {
					if (hasAuthority) {
						if (ideaDeveloper.blockedEnt.contains(entity)) {
							ideaDeveloper.blockedEnt.remove(entity);
							entity.blocked.remove(ideaDeveloper);
							ideaDeveloper.save();
							entity.save();
							Log log = new Log("^ blocked from entity ^");
							log.ids = ideadev.id + "," + ideaDeveloper.id;
							log.types = "developer,developer";
							log.save();
							json.addProperty("output",
									"Idea developer has been unblocked from entity");
						} else {
							json.addProperty("output",
									"Idea developer is not blocked from this entity");
						}
					} else {
						json.addProperty("output",
								"Sorry u have no authority on this entity");
					}
				}

			}
		}
		renderJSON(json.toString());

	}

	/**
	 * This method is used to block an ideaDeveloper from an organization by an
	 * organization lead
	 * 
	 * @Maryam
	 * 
	 * @param ideadeveloperName
	 *            The name of the ideaDeveloper that is going to be blocked
	 * @param organizationId
	 *            the id of the organization that the ideaDeveloper will be
	 *            blocked from
	 */
	public static void blockFromOrganization(String organizationName,
			String ideadeveloperName, String reason) {

		JsonObject json = new JsonObject();
		Long loggedInUserID = Security.userid();

		IdeaDeveloper ideadev = IdeaDeveloper.findById(loggedInUserID);
		long countorganizations = Organization.count("name = ?",
				organizationName);
		if (countorganizations == 0) {
			json.addProperty("output", "Organization not found");
		} else {

			Organization organization = (Organization) Organization
					.find("name= ?", organizationName).fetch().get(0);

			boolean hasAuthority = ideadev.canLeadOrganization(ideadev,
					organization);
			long countUser = IdeaDeveloper.count("username = ?",
					ideadeveloperName);
			if (countUser == 0) {
				json.addProperty("output", "User not found");
			} else {

				IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
						.find("username = ?", ideadeveloperName).fetch().get(0);
				boolean isMember = organization.members.contains(ideaDeveloper);
				boolean isLead = false;

				for (int i = 0; i < organization.managers.size(); i++) {
					if (organization.managers.get(i).ideaDeveloper
							.equals(ideaDeveloper)) {
						isLead = true;
					}
				}
				if (isLead) {
					json.addProperty("output",
							"Sorry user cant be blocked,they're an organzation lead to this organization ");
				} else {
					if (!isMember) {
						json.addProperty("output",
								"Idea developer is not a member in this organization");
					} else {
						if (hasAuthority) {
							if (!ideaDeveloper.blockedOrg
									.contains(organization)) {
								ideaDeveloper.blockedOrg.add(organization);
								organization.blocked.add(ideaDeveloper);
								ideaDeveloper.save();
								organization.save();
								Log log = new Log(
										"^ blocked from organization ^");
								log.ids = ideadev.id + "," + ideaDeveloper.id;
								log.types = "developer,developer";
								log.save();
								String block = "has blocked you from their organization with the following reasons: "
										+ reason;
								Notification.notify(block, ideaDeveloper,
										ideadev, new Date());
								block = "has blocked "+ ideaDeveloper.username+ " from the organization with the following reasons: "
										+ reason;
								for (int i = 0; i < organization.liesIn.size(); i++) {
									for (int j = 0; j < organization.liesIn
											.get(i).managers.size(); j++) {
										IdeaDeveloper organizer = organization.liesIn
												.get(i).managers.get(j).ideaDeveloper;
										Notification.notify(block, organizer,
												ideadev, new Date());
									}
								}
								json.addProperty("output",
										"Idea developer has been blocked from organization");
							} else {
								json.addProperty("output",
										"Idea developer is already blocked from this organization");
							}
						} else {
							json.addProperty("output",
									"Sorry u have no authority on this organization");
						}
					}
				}

			}
		}
		renderJSON(json.toString());

	}

	/**
	 * This method is used to unblock an ideaDeveloper from an organization by
	 * an organization lead
	 * 
	 * @Maryam
	 * 
	 * @param ideadeveloperName
	 *            The name of the ideaDeveloper that is going to be unblocked
	 * @param organizationId
	 *            the id of the organization that the ideaDeveloper will be
	 *            unblocked from
	 */
	public static void unblockFromOrganization(String organizationName,
			String ideadeveloperName, String reason) {

		JsonObject json = new JsonObject();
		Long loggedInUserID = Security.userid();

		IdeaDeveloper ideadev = IdeaDeveloper.findById(loggedInUserID);
		long countorganizations = Organization.count("name = ?",
				organizationName);
		if (countorganizations == 0) {
			json.addProperty("output", "Organization not found");
		} else {

			Organization organization = (Organization) Organization
					.find("name = ?", organizationName).fetch().get(0);

			boolean hasAuthority = ideadev.canLeadOrganization(ideadev,
					organization);
			long countUser = IdeaDeveloper.count("username = ?",
					ideadeveloperName);
			if (countUser == 0) {
				json.addProperty("output", "User not found");
			} else {

				IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
						.find("username = ?", ideadeveloperName).fetch().get(0);
				boolean isMember = organization.members.contains(ideaDeveloper);
				boolean isLead = false;

				for (int i = 0; i < organization.managers.size(); i++) {
					if (organization.managers.get(i).ideaDeveloper
							.equals(ideaDeveloper)) {
						isLead = true;
					}
				}
				if (isLead) {
					json.addProperty("output",
							"Sorry user cant be blocked,they're an organzation lead to this organization ");
				} else {
					if (!isMember) {
						json.addProperty("output",
								"Idea developer is not a member in this organization");
					} else {
						if (hasAuthority) {
							if (ideaDeveloper.blockedOrg.contains(organization)) {
								ideaDeveloper.blockedOrg.remove(organization);
								organization.blocked.remove(ideaDeveloper);
								ideaDeveloper.save();
								organization.save();
								Log log = new Log(
										"^ blocked from organization ^");
								log.ids = ideadev.id + "," + ideaDeveloper.id;
								log.types = "developer,developer";
								log.save();
								String unblock = "has blocked "+ ideaDeveloper.username+ " from the organization with the following reasons: "
										+ reason;
								Notification.notify(unblock, ideaDeveloper,
										ideadev, new Date());

								unblock = "has unblocked from organization with the following reasons: "
										+ reason;
								for (int i = 0; i < organization.liesIn.size(); i++) {
									for (int j = 0; j < organization.liesIn
											.get(i).managers.size(); j++) {
										IdeaDeveloper organizer = organization.liesIn
												.get(i).managers.get(j).ideaDeveloper;
										Notification.notify(unblock, organizer,
												ideadev, new Date());

									}
								}
								json.addProperty("output",
										"Idea developer has been unblocked from organization");
							} else {
								json.addProperty("output",
										"Idea developer is not blocked from this organization");
							}
						} else {
							json.addProperty("output",
									"Sorry u have no authority on this organization");
						}
					}
				}

			}
		}
		renderJSON(json.toString());

	}

}
